:- module(utils, [
        show_list/2, 
        remove_dir/2,
        split_llist_into_atoms/2,
        split_into_atoms/2,
        split_into_atoms_dollars/2,
        atoms_and_strings/2,
	atom_concat_with_dollars/2,
        split_in_lines/2,
	new/2,
        log_message/1,
        to_lowercase/2
                 ], []).

:- use_module(library(system), [get_pid/1,chmod/2,getenvstr/2]).

:- use_module(library(write)).
:- use_module(library(strings)).
:- use_module(library(atom2term)).
:- use_module(library(lists)).
:- use_module(library(terms)).


:- use_module(amos(configuration), [log_dir/1]).

:- set_prolog_flag(write_strings, on).

show_list(Message, List):-
        write('======================================================='),
        nl,
        write(Message),
        nl,
        show(List).


show([]).
show([Item|Items]):-
        writeq(Item),
        nl,
        show(Items).


remove_dir(WithDir, NoDir):-
        (
            WithDir = "/"||FirstStep ->
            true
        ;
            FirstStep = WithDir
        ),
        skip_until_slash(FirstStep, NextSlash, ThereWasSlash),
        (
            ThereWasSlash = true ->
            remove_dir(NextSlash, NoDir)
        ;
            NoDir = FirstStep
        ).

skip_until_slash("", "", false).                  % No slash
skip_until_slash("/"||Rest, "/"||Rest, true):- !. % Next slash found.
skip_until_slash([_|Cs], Rest, T):-
        skip_until_slash(Cs, Rest, T).


%% Given a string, decompose it into atoms using $$ as separators
split_into_atoms([], []).
split_into_atoms(" "||RestStr, RestAtoms):-
        !,
        split_into_atoms(RestStr, RestAtoms).
split_into_atoms(AtomStarts, [Atom|RestAtoms]):-
        AtomStarts \== [],
        first_atom(AtomStarts, String, RestString," "),
        atom_codes(Atom, String),
        split_into_atoms(RestString, RestAtoms).

split_into_atoms_dollars([], []).
split_into_atoms_dollars("$$"||RestStr, RestAtoms):-
        !,
        split_into_atoms_dollars(RestStr, RestAtoms).
split_into_atoms_dollars(AtomStarts, [Atom|RestAtoms]):-
        AtomStarts \== [],
        first_atom(AtomStarts, String, RestString,"$$"),
        atom_codes(Atom, String),
        split_into_atoms_dollars(RestString, RestAtoms).

first_atom("", "", "",_Separator).
first_atom(Ys, "", Xs, Separator):- 
	append(Separator, Xs, Ys), !.
first_atom([X|Xs], [X|As], Ys, Separator):-
        first_atom(Xs, As, Ys, Separator).

atoms_and_strings([],[]).
atoms_and_strings([A|As], [S|Ss]):-
        atom_codes(A, S),
        atoms_and_strings(As, Ss).

split_in_lines([], []).
split_in_lines([A|As], [A, \\|Bs]):- split_in_lines(As, Bs).

split_llist_into_atoms([], []).
split_llist_into_atoms([L|Ls], [A|As]) :-
%jcf%	string2term(L, A),
	atom_codes(A,L),
	split_llist_into_atoms(Ls, As).

%% -----------------------------------------------------------------

new([],_).
new([Packages|Ps], Candidate) :-
	(match(Candidate, Packages) ->
	 fail
	;
	 new(Ps, Candidate)) .

match([], []) .
match([C|Cs], Packages) :-
	delete(Packages, C, NewPackages),
	match(Cs, NewPackages).

atom_concat_with_dollars([], '').
atom_concat_with_dollars([A|As], R) :-
	atom_concat_with_dollars(As, R1),
	atom_concat([A, '$$', R1], R).

	
filename(FileName):-
        log_dir(LogDirAt),
        atom_codes(LogDirAt, LogDir),
        (
            getenvstr('USER', UserName) ->
            true
        ; 
            UserName = "no_user_name"
        ),
        append(LogDir, "/Amos-log-", LogBase),
        append(LogBase, UserName, File),
        atom_codes(FileName, File).

log_message(M):-
        filename(F),
        open(F, append, S),
        writeq(S, M),
        nl(S),
        close(S).
%        chmod(F, 0o666).
 

% Converts a descriptor to lowercase
to_lowercase(Mixed, Lower):-
        functor(Mixed, FunctName, Arity),
        (
            Arity = 0 ->   % A constant
            Lower = L1,
            Mixed = M1
        ;
            functor(Lower, FunctName, Arity),
            arg(1, Mixed, M1),
            arg(1, Lower, L1)
        ),
        atom_codes(M1, MixedCodes),
        to_lowercase_codes(MixedCodes, LowerCodes),
        atom_codes(L1, LowerCodes).

to_lowercase_codes([], []).
to_lowercase_codes([M|Ms], [L|Ls]):-
        % Strip out functors
        (
            0'A =< M, M =< 0'Z ->
            L is M + (0'a - 0'A)
        ;
            L = M
        ),
        to_lowercase_codes(Ms, Ls).
